package cn.study.jmm;


import cn.study.cas.unsafe.UnsafeInstance;
import lombok.extern.slf4j.Slf4j;

/**
 * @Author     ：跟大佳一起学
 * @Description：
 *  * -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -Xcomp
 *  *  将hsdis-amd64.dll放在
 *      windows : $JAVA_HOME/jre/bin/server 目录下
 *      mac:      /Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/
 *  *
 */

@Slf4j
public  class VisibilityTest {
    private boolean flag = true;

    /**
     * @description:
     * 1、refresh 方法加synchronized、内部加
     * 2、load 方法加synchronized
     * @return void
     */
    // TODO:
    public void refresh() {

        while (true) {
            synchronized(VisibilityTest.class){
                flag = false;
            }
        }
    }
    public void load() {
        System.out.println(Thread.currentThread().getName() + "开始执行.....");
        while (flag) {
//            synchronized(VisibilityTest.class) {}
//            UnsafeInstance.reflectGetUnsafe().storeFence();
//            System.out.println("正在加载数据......");
//            volitile
//            shortWait(20000);  // 0.00002 秒(s)
//            try {
//                Thread.sleep(1000);
//            } catch (InterruptedException e) {
//                throw new RuntimeException(e);
//            }
        }
        System.out.println(Thread.currentThread().getName() + "数据加载完成，跳出循环");
    }

    public static void main(String[] args) throws InterruptedException {
        VisibilityTest test = new VisibilityTest();
        // 线程threadA模拟数据加载场景
        Thread threadA = new Thread(() -> test.load(), "threadA");
        threadA.start();
        // 让threadA先执行一会儿后再启动线程B
        Thread.sleep(1000);
        // 线程threadB通过修改flag控制threadA的执行时间，数据加载可以结束了
        Thread threadB = new Thread(() -> test.refresh(), "threadB");
        threadB.start();
    }

    /**
     * @description: 10000
     * @param interval
     * @return void
     */
    public static void shortWait(long interval){
        long start = System.nanoTime();
        long end;
        do{
            end = System.nanoTime();
        }while(start + interval >= end);
    }
}
